package simtester.server

import groovy.time.TimeCategory
import groovy.time.TimeDuration
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Date

class TestRun {
    static belongsTo = [testcase: TestCase, testsuite: TestSuite]
    static hasMany   = [iterations: Iteration, instances: Instance]

    String status
    String name = ''
    String type = 'GUI'
    //List instances
    //List results
    List iterations
    List testcaseIds
    Integer repeats = 1
    Integer users = 1
    Map usersPerTest
    Long testDuration
    Date dateCreated
    Date lastUpdated
    Date endDate
    
    static private final DateFormat dateFormat = new SimpleDateFormat('MM/dd/yyyy HH:mm:ss.SSS')

    static constraints = {
        endDate nullable: true
        repeats nullable: true
        testDuration nullable: true
        testcase nullable: true
        testsuite nullable: true
        usersPerTest nullable: true
    }
    
    static mapping = {
        iterations lazy: false
    }


    def findResults(args = [:]) {
        long min = args.min ?: 0L
        Date minDate = new Date(min)
        
        def entries
        if (args.user) {
            entries = ResultEntry.withCriteria {
                ge 'timestamp', minDate
                eq 'testrun', this
                if (args.testcase) {
                    eq 'testcase', args.testcase
                }
                eq 'user', args.user
                eq 'iteration', args.iter
            }
        } else {
            entries = ResultEntry.withCriteria {
                eq 'testrun', this
            }
        }

        return entries.collect {
            StringBuilder str = new StringBuilder(128)
            str.append( dateFormat.format(it.timestamp) )
            str.append(' ')
            str.append(it.level)
            str.append(': ')
            
            if (it.type) {
                str.append(it.type)
                str.append(' ')
            }
            
            str.append(it.entry)
            
            [time: it.timestamp.time, output: str.toString()]
        }
    }
    
    def getDuration() {
        if (!endDate) {
            return -1
        } else {
            use(TimeCategory) {
                return (endDate - dateCreated)
            }
        }
    }
    
    def getPlannedDuration() {
        int secs = this.testDuration / 1000
        use (TimeCategory) {
            new TimeDuration(0, 0, secs, 0)
        }
    }
    
    def instanceIds() {
        return this.instances.collect { it.cloudId }
    }
    
    def log(ResultEntry resultEntry) {
        resultEntry.save(flush: true)
        
        //this.addToResults(resultEntry)
        
        //boolean saveSuccessful = false
        //while (!saveSuccessful) {
        //    try {
                //this.save(flush: true)
        //        saveSuccessful = true
        //    } catch (org.springframework.dao.OptimisticLockingFailureException e) { println "log: Lock Exception" }
        //}
    }
    
    def log(String msg) {
        log( new ResultEntry(testrun: this, timestamp: new Date(), level: 'INFO', entry: msg, user: 1, iteration: 1) )
    }

}
